import {
    Avatar,
    Button,
    Card,
    Col,
    Divider,
    Flex,
    FloatButton,
    Form,
    Image,
    Layout,
    List,
    message,
    Popconfirm,
    Row,
    Skeleton,
    Tabs
} from "antd";
import {Column, Pie} from '@ant-design/plots';
import axios from "axios";
import React, {useContext, useEffect, useState} from "react";
import {hostContext} from "../store/commonContext.jsx";
import cookie from "js-cookie"
import '../assets/charge.css'
import logo from '../../public/image/TimeSpace-logo.jpg'
import ChargeModal from "../components/charge/ChargeModal.jsx";
import CategoryModal from "../components/category/CategoryModal.jsx";
import {HeartTwoTone, LeftCircleTwoTone, MoneyCollectTwoTone, RightCircleTwoTone} from "@ant-design/icons";
import AvatarPopover from "../components/user/AvatarPopover.jsx";
import ChargeTableComponent from "../components/charge/ChargeTableComponent.jsx";
import ChargeSearchInput from "../components/charge/ChargeSearchInput.jsx";
import ChargeSelectInput from "../components/charge/ChargeSelectInput.jsx";
import ChargeYearInput from "../components/charge/ChargeYearInput.jsx";
import ChargeMonthInput from "../components/charge/ChargeMonthInput.jsx";
import ChargeDateInput from "../components/charge/ChargeDateInput.jsx";
import InfiniteScroll from "react-infinite-scroll-component";
import TextArea from "antd/es/input/TextArea.js";

const {Header, Sider, Content} = Layout;

const layoutStyle = {
    borderRadius: 0,
    overflow: 'hidden',
    width: 'calc(100%)',
    /*控制整个layout铺满屏幕*/
    minHeight: '100vh'
};
const headerStyle = {
    color: '#fff',
    backgroundColor: '#3F39E9',
};
const iconColStyle = {
    display: 'flex',
    alignItems: 'center',
    height: '8vh',
}
const menuColStyle = {
    display: 'flex',
    justifyContent: 'flex-start',
    alignItems: 'center'
}
const avatarColStyle = {
    display: 'flex',
    justifyContent: 'flex-end',
    alignItems: 'center',
}
const tabsStyle = {
    marginLeft: 20,
    marginRight: 20,
    marginBottom: 20,
    marginTop: 20
}
const siderStyle = {
    backgroundColor: 'rgba(22,119,255,0.26)',
};
const categoryPieStyle = {
    display: 'flex',
    justifyContent: 'space-around',
    marginLeft: 20,
    marginRight: 20,
    marginTop: 20,
    marginBottom: 20,
}
const searchStyle = {
    display: 'flex',
    alignItems: 'center',
    paddingRight: 20
}
/*按钮的上下间距*/
const buttonMarginStyle = {
    marginTop: 8,
    marginBottom: 8,
    marginLeft: 20
}

const Charge = () => {
    const host = useContext(hostContext)
    const token = cookie.get('access_token')
    const userId = cookie.get('user_id')
    const requestHeader = {headers: {'Authorization': 'Bearer ' + token}}

    const [user, setUser] = useState({})
    const [categoryList, setCategoryList] = useState([])
    const [chargeData, setChargeData] = useState([])
    const [yearChargeData, setYearChargeData] = useState([])
    const [yearCategoryData, setYearCategoryData] = useState([])
    const [commentsData, setCommentsData] = useState([])
    const [comments, setComments] = useState('')
    const [pagination, setPagination] = useState({current: 1, pageSize: 10})
    const year = new Date().getFullYear()
    const [commentsHidden, setCommentsHidden] = useState(false)

    // 封装工具函数
    function buildUrl(baseUrl, params) {
        const filtered = Object.entries(params).reduce((acc, [key, value]) => {
            if (value != null && value !== '') { // 过滤 null/undefined/空字符串
                acc[key] = value;
            }
            return acc;
        }, {});
        // moment对象，可以自己打印，看看有什么属性，自己拼接
        // 这里不可以在子组件中，传递onChange
        if (filtered.yearStr !== '' && filtered.yearStr !== undefined) {
            filtered.yearStr = filtered['yearStr'].$y
        }
        if (filtered.monthStr !== '' && filtered.monthStr !== undefined) {
            let year = filtered['monthStr'].$y
            let month = filtered['monthStr'].$M < 10 ? "0" + (filtered['monthStr'].$M + 1) : (filtered['monthStr'].$M + 1)
            filtered.monthStr = year + '-' + month
        }
        if (filtered.dateStr !== '' && filtered.dateStr !== undefined) {
            let year = filtered['dateStr'].$y
            let month = filtered['dateStr'].$M < 10 ? "0" + (filtered['dateStr'].$M + 1) : (filtered['dateStr'].$M + 1)
            let day = filtered['dateStr'].$D < 10 ? "0" + filtered['dateStr'].$D : filtered['dateStr'].$D
            filtered.dateStr = year + '-' + month + '-' + day
        }
        const query = new URLSearchParams(filtered).toString();
        return query ? `${baseUrl}?${query}` : baseUrl;
    }

    // 新增加载状态
    const [loading, setLoading] = useState(false);
    // 这里的total用来控制table数据为空时的显示
    const [total, setTotal] = useState(0)
    const fetchChargeData = async (params) => {
        try {
            setLoading(true);
            let url = buildUrl(`${host}/charge/select-charge`, params)
            console.log(url)
            const response = await axios.get(url, requestHeader)
            let chargeList = response.data.data.list
            let emptyCharge = [{
                chargeId: '',
                chargeNum: '',
                date: '',
                amount: '',
                category: '',
                remarks: '',
                createdBy: '',
                deleteFlag: '',
                type: '',
                creationDate: ''
            }]
            chargeList = response.data.data.list.length === 0 ? emptyCharge : chargeList
            if (response.data.data.total !== 0) {
                chargeList.forEach(c => c.key = c.chargeId);
                setTotal(1)
            } else {
                setTotal(0)
            }
            setChargeData(chargeList)
            setPagination({
                current: response.data.data.pageNum,
                pageSize: response.data.data.pageSize,
                total: response.data.data.total,
                position: ["bottomCenter"]
            })
        } finally {
            setLoading(false);
        }
    }

    const fetchUserInfo = async () => {
        const user = await axios.get(`${host}/oauth/self/${userId}`, requestHeader)
        let birthday = user.data.birthday
        let arr = birthday.split('-')
        setUser({
            ...user.data,
            year: arr[0] || '',
            monthS: arr[1] || '',
            dayS: arr[2] || ''
        })
    }

    const fetchCategoryList = async () => {
        const response = await axios.get(host + `/category/select-all?userId=${userId}`, requestHeader)
        let categoryList = []
        categoryList = response.data.data
        categoryList.map(c => {
            c.key = c.id
            c.edit = ''
        })
        setCategoryList(categoryList || [])
    }

    const fetchYearChargeData = async (year) => {
        const response = await axios.get(`${host}/charge/year-data?year=${year}&userId=${userId}`, requestHeader
        )
        setYearChargeData(response.data.data || [])
    }

    const fetchYearCategoryCountData = async (year) => {
        const response = await axios.get(`${host}/charge/category-count?year=${year}&userId=${userId}`, requestHeader
        )
        setYearCategoryData(response.data.data || [])
    }

    const [commentsLoading, setCommentsLoading] = useState(false)
    const fetchAllCommentsData = async () => {
        if (commentsLoading) {
            return;
        }
        setCommentsLoading(true)
        await axios.get(`${host}/comments/select-all`, requestHeader)
            .then(response => {
                setCommentsData(response.data.data || [])
                setCommentsLoading(false)
            })
            .catch(() => {
                setCommentsLoading(false)
            })

    }

    useEffect(() => {
        fetchUserInfo()
        fetchChargeData(searchKeys)
        fetchCategoryList()
        fetchYearChargeData(year)
        fetchYearCategoryCountData(year)
        fetchAllCommentsData()
    }, [])

    const handleTableChange = (pagination) => {
        const params = {
            ...searchKeys,
            pageNum: pagination.current,
            pageSize: pagination.pageSize
        }
        fetchChargeData(params)
    };

    const [openCharge, setOpenCharge] = useState(false);
    const [openCategory, setOpenCategory] = useState(false);
    const [confirmLoadingCharge, setConfirmLoadingCharge] = useState(false);
    const [confirmLoadingCategory, setConfirmLoadingCategory] = useState(false);
    const [form] = Form.useForm()
    const showChargeModel = () => {
        setOpenCharge(true)
    }
    const showCategoryModel = () => {
        setOpenCategory(true)
    }
    const handleSubmitCharge = async (values) => {
        let date = values.date += ':00'
        date = date.replace('T', ' ')
        let createdBy = cookie.get('user_id')
        setConfirmLoadingCharge(true)
        try {
            await axios.post(host + '/charge/save-charge',
                {
                    date: date,
                    type: values.type,
                    amount: values.amount,
                    category: values.category,
                    remarks: values.remarks,
                    createdBy: createdBy
                },
                requestHeader
            ).then(response => {
                console.log(response)
            })
            setOpenCharge(false)
            form.resetFields();
            location.reload()
        } catch (error) {
            message.error(error.message)
        } finally {
            setConfirmLoadingCharge(false)
        }
    }

    const downloadFile = async (url, fileName) => {
        try {
            // 1.发起请求
            const response = await axios.get(
                url,
                {
                    headers: {'Authorization': 'Bearer ' + token},
                    responseType: 'blob'
                }
            )
            // 3. 创建虚拟链接并触发下载
            const blob = new Blob([response.data]);
            const link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);
            link.download = fileName; // 设置下载文件名
            document.body.appendChild(link);
            link.click();

            // 4. 清理内存
            window.URL.revokeObjectURL(link.href);
            document.body.removeChild(link);
        } catch (error) {
            console.error('下载失败:', error);
        }
    }

    // 定义搜索参数
    const [searchKeys, setSearchKeys] = useState({
        chargeNum: '',
        type: '',
        category: '',
        yearStr: '',
        monthStr: '',
        dateStr: '',
        pageNum: pagination.current,
        pageSize: pagination.pageSize,
        createdBy: userId
    })

    const handleClearSearch = () => {
        setSearchKeys({
            chargeNum: '',
            type: '',
            category: '',
            yearStr: '',
            monthStr: '',
            dateStr: '',
            pageNum: pagination.current,
            pageSize: pagination.pageSize,
            createdBy: userId
        })
    }

    const onValueChange = (key) => (value) => {
        setSearchKeys(prev => ({
            ...prev,
            [key]: value
        }))
    }

    const handleCommentsChange = (e) => {
        setComments(e.target.value);
    }
    const clearComments = () => {
        setComments('')
    }
    const handleCommitComments = async () => {
        let saveComments = {
            userId: userId,
            title: user.nickName,
            description: comments
        }
        const response = await axios.post(`${host}/comments/save`, saveComments, requestHeader)
        if (response.status === 200) {
            setComments('')
            fetchAllCommentsData()
        }
    }
    const handleDeleteComments = async (id) => {
        const response = await axios.get(`${host}/comments/delete/${id}`, requestHeader)
        console.log(response)
        if (response.status === 200) {
            fetchAllCommentsData()
        }
    }

    const handleSetYear = (key) => (value) => {
        setSearchKeys(prev => ({...prev, [key]: value}));
    };

    const yearConfig = {
        title: `${year}年全数据图`,
        data: yearChargeData,
        xField: 'month',
        yField: 'amount',
        colorField: 'type',
        group: true,
        label: {
            text: (d) => d.amount,
            textBaseline: 'bottom'
        },
        style: {
            fill: ({type}) => {
                if (type === '收入') {
                    return '#2db7f5'
                }
                return '#f50'
            }
        }
    }

    const leftCategoryCountConfig = {
        data: yearCategoryData,
        angleField: 'count',
        colorField: 'categoryType',
        innerRadius: 0.4,
        label: {
            text: 'count'
        },
        legend: {
            color: {
                title: false,
                position: 'right',
                rowPadding: 5,
            },
        },
        annotations: [
            {
                type: 'text',
                style: {
                    text: `${year}年\n总次数`,
                    x: '50%',
                    y: '50%',
                    textAlign: 'center',
                    fontSize: 30,
                    fontStyle: 'bold',
                },
            },
        ],
        tooltip: {
            title: 'categoryType'
        },
        interaction: {
            elementHighlight: true,
        },
        state: {
            inactive: {opacity: 0.5},
        },
    };

    const rightCategoryCountConfig = {
        data: yearCategoryData,
        angleField: 'amount',
        colorField: 'categoryType',
        innerRadius: 0.4,
        label: {
            text: 'amount'
        },
        legend: {
            color: {
                title: false,
                position: 'right',
                rowPadding: 5,
            },
        },
        annotations: [
            {
                type: 'text',
                style: {
                    text: `${year}年\n总金额`,
                    x: '50%',
                    y: '50%',
                    textAlign: 'center',
                    fontSize: 30,
                    fontStyle: 'bold',
                },
            },
        ],
        tooltip: {
            title: 'categoryType'
        },
        interaction: {
            elementHighlight: true,
        },
        state: {
            inactive: {opacity: 0.5},
        },
    };

    const PlotMaps = {}
    if (!Object.keys(chargeData).length) {
        return null;
    }
    const showCategoryToolTip = (evt, pie) => {
        Object.keys(PlotMaps).forEach((plot) => {
            if (plot !== pie) {
                PlotMaps[plot].chart.emit('tooltip:show', {
                    data: {data: {categoryType: evt.data.data.categoryType}}
                })
                PlotMaps[plot].chart.emit('element:highlight', {
                    data: {data: {categoryType: evt.data.data.categoryType}}
                })
            }
        })
    }
    const hideCategoryToolTip = (evt, pie) => {
        Object.keys(PlotMaps).forEach((plot) => {
            if (plot !== pie) {
                PlotMaps[plot].chart.emit('tooltip:hide', {
                    data: {data: {categoryType: evt.data.data.categoryType}}
                })
                PlotMaps[plot].chart.emit('element:unhighlight', {
                    data: {data: {categoryType: evt.data.data.categoryType}}
                })
            }
        })
    }

    const tabItems = [
        {
            key: '1',
            label: '年度全数据图',
            icon: <HeartTwoTone/>,
            children: (
                <Column {...yearConfig}/>
            )
        },
        {
            key: '2',
            label: '年度分类数据图',
            icon: <MoneyCollectTwoTone/>,
            children: (
                <div style={categoryPieStyle}>
                    <Pie
                        {...leftCategoryCountConfig}
                        style={{width: '50%'}}
                        onReady={(plot) => {
                            PlotMaps.leftPie = plot
                            plot.chart.on('interval:pointerover', (evt) => {
                                showCategoryToolTip(evt, 'leftPie')
                            });
                            plot.chart.on('interval:pointerout', (evt) => {
                                hideCategoryToolTip(evt, 'leftPie')
                            });
                        }}
                    />
                    <Pie
                        {...rightCategoryCountConfig}
                        style={{width: '50%'}}
                        onReady={(plot) => {
                            PlotMaps.rightPie = plot;
                            plot.chart.on('interval:pointerover', (evt) => {
                                showCategoryToolTip(evt, 'rightPie');
                            });
                            plot.chart.on('interval:pointerout', (evt) => {
                                hideCategoryToolTip(evt, 'rightPie');
                            });
                        }}
                    />
                </div>
            )
        }
    ]

    return (
        <>
            <FloatButton
                shape="circle"
                type="primary"
                style={{right: 24, top: 80}}
                icon={commentsHidden ? <LeftCircleTwoTone/> : <RightCircleTwoTone/>}
                onClick={() => {
                    setCommentsHidden(!commentsHidden)
                }}
            />
            <Flex gap="middle" wrap>
                <Layout style={layoutStyle}>
                    <Header style={headerStyle}>
                        <Row gutter={{
                            xs: 8,
                            sm: 16,
                            md: 24,
                            lg: 32,
                        }}
                        >
                            <Col span={8} style={iconColStyle}>
                                <Image
                                    src={logo}
                                    preview={false}
                                    style={{
                                        width: 240,
                                        objectFit: 'cover'
                                    }}
                                />
                            </Col>
                            <Col span={8} style={menuColStyle}></Col>
                            <Col span={8} style={avatarColStyle}>
                                <AvatarPopover
                                    user={user}
                                />
                            </Col>
                        </Row>
                    </Header>
                    <Layout>
                        <Layout>
                            <Card style={{marginBottom: 4}}>
                                <Row gutter={{
                                    xs: 8,
                                    sm: 16,
                                    md: 24,
                                    lg: 32,
                                }}
                                     style={{paddingBottom: 8}}
                                >
                                    <Col span={6} style={searchStyle}>
                                        <ChargeSearchInput
                                            value={searchKeys.chargeNum}
                                            label="流水号"
                                            onChange={onValueChange('chargeNum')}
                                        />
                                    </Col>
                                    <Col span={3}></Col>
                                    <Col span={6} style={searchStyle}>
                                        <ChargeSelectInput
                                            value={searchKeys.type}
                                            label="种类"
                                            options={[
                                                {value: "in", label: "收入"},
                                                {value: "out", label: "支出"}
                                            ]}
                                            onChange={onValueChange('type')}
                                        />
                                    </Col>
                                    <Col span={3}></Col>
                                    <Col span={6} style={searchStyle}>
                                        <ChargeSelectInput
                                            value={searchKeys.category}
                                            label="分类"
                                            options={categoryList}
                                            onChange={onValueChange('category')}
                                        />
                                    </Col>
                                </Row>
                                <Row gutter={{
                                    xs: 8,
                                    sm: 16,
                                    md: 24,
                                    lg: 32,
                                }}
                                     style={{paddingBottom: 2}}
                                >
                                    <Col span={6} style={searchStyle}>
                                        <ChargeYearInput
                                            value={searchKeys.yearStr}
                                            label="年份"
                                            onChange={handleSetYear('yearStr')}
                                        />
                                    </Col>
                                    <Col span={3}></Col>
                                    <Col span={6} style={searchStyle}>
                                        <ChargeMonthInput
                                            value={searchKeys.monthStr}
                                            label="月份"
                                            onChange={onValueChange('monthStr')}
                                        />
                                    </Col>
                                    <Col span={3}></Col>
                                    <Col span={6} style={searchStyle}>
                                        <ChargeDateInput
                                            value={searchKeys.dateStr}
                                            label="日期"
                                            onChange={onValueChange('dateStr')}
                                        />
                                    </Col>
                                </Row>
                                <Row style={{display: 'flex', justifyContent: 'flex-end', alignItems: 'center'}}>
                                    <Col>
                                        <Button
                                            style={buttonMarginStyle}
                                            onClick={handleClearSearch}
                                        >
                                            重置
                                        </Button>
                                    </Col>
                                    <Col>
                                        <Button
                                            type="primary"
                                            style={buttonMarginStyle}
                                            onClick={handleTableChange}
                                        >
                                            查询
                                        </Button>
                                    </Col>
                                </Row>
                            </Card>
                            <ChargeTableComponent
                                downloadFile={downloadFile}
                                showChargeModel={showChargeModel}
                                showCategoryModel={showCategoryModel}
                                handleTableChange={handleTableChange}
                                pagination={pagination}
                                chargeData={chargeData}
                                loading={loading}
                                total={total}
                            />
                            <Content style={tabsStyle}>
                                <Tabs
                                    items={tabItems}
                                />
                            </Content>
                        </Layout>
                        <Sider style={siderStyle} width='20%'  hidden={commentsHidden}>
                            <div id="srcollableDiv"
                                 style={{
                                     height: 650,
                                     width: '98%',
                                     overflow: 'auto',
                                     border: '3px solid rgba(140, 140, 140, 0.35)',
                                 }}>
                                <InfiniteScroll
                                    dataLength={commentsData.length}
                                    next={fetchAllCommentsData}
                                    hasMore={commentsData.length < 5}
                                    loader={
                                        <Skeleton
                                            avatar
                                            paragraph={{
                                                rows: 1
                                            }}
                                            active
                                        />
                                    }
                                    endMessage={<Divider>没有更多啦🤐</Divider>}
                                    scrollableTarget="srcollableDiv"
                                >
                                    <List
                                        itemLayout="horizontal"
                                        dataSource={commentsData}
                                        bordered
                                        size="small"
                                        renderItem={(item, index) => (
                                            <List.Item>
                                                <List.Item.Meta
                                                    avatar={<Avatar src={item.avatar}/>}
                                                    title={item.nickName}
                                                    description={item.description}
                                                />
                                                {userId === item.userId.toString() ?
                                                    (<Popconfirm
                                                        title='注意'
                                                        description='确定要删除吗？'
                                                        onConfirm={() => handleDeleteComments(item.id)}
                                                        okText='确定'
                                                        cancelText='取消'
                                                        key="pop"
                                                    >
                                                        <Button color="danger" variant="filled"
                                                                size={"small"}>删除</Button>
                                                    </Popconfirm>)
                                                    :
                                                    (<></>)
                                                }
                                                &nbsp;&nbsp; | --{item.creationDate} |
                                            </List.Item>
                                        )}
                                    />
                                </InfiniteScroll>
                            </div>
                            <div>
                                <TextArea rows={3}
                                          style={{
                                              width: '93%'
                                          }}
                                          onChange={handleCommentsChange}
                                          value={comments}
                                />
                                <Row style={{display: 'flex'}}>
                                    <Col span={10}></Col>
                                    <Col span={4}>
                                        <Button onClick={clearComments}>清空</Button>
                                    </Col>
                                    <Col span={2}></Col>
                                    <Col span={4}>
                                        <Button type="primary" onClick={handleCommitComments}>发送</Button>
                                    </Col>
                                </Row>
                            </div>

                        </Sider>
                    </Layout>
                    {/*<Footer style={footerStyle}>Footer</Footer>*/}
                </Layout>
            </Flex>

            <ChargeModal
                visible={openCharge}
                onCancel={() => setOpenCharge(false)}
                onSubmit={handleSubmitCharge}
                confirmLoading={confirmLoadingCharge}
                categoryList={categoryList}
            />

            <CategoryModal
                visible={openCategory}
                onCancel={() => setOpenCategory(false)}
                confirmLoading={confirmLoadingCategory}
                categoryList={categoryList}
                setCategoryList={setCategoryList}
                fetchCategoryList={fetchCategoryList}
            />
        </>
    )


}

export default Charge;